package com.mky.mkcompany.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mky.mkcompany.controller.domain.DoCourseSaveReq;
import com.mky.mkcompany.controller.domain.DoPracticeReq;
import com.mky.mkcompany.controller.domain.DoTestSaveReq;
import com.mky.mkcompany.dao.*;
import com.mky.mkcompany.model.*;
import com.mky.mkcompany.model.view.UserFalseQuest;
import com.mky.mkcompany.tool.Arith;
import com.mky.mkcompany.tool.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.sql.Timestamp;
import java.util.*;

/**
 * Created by Lenovo on 2017/9/1.
 */
@Service
public class UserCourseService {
    private final Logger LOGGER = LoggerFactory.getLogger(getClass());
    @Autowired
    private CourseCategoryDao courseCategoryDao;
    @Autowired
    private CourseSubjectDao courseSubjectDao;
    @Autowired
    private CourseInfoDao courseInfoDao;
    @Autowired
    private CourseQuestDao courseQuestDao;
    @Autowired
    private UserCourseDao userCourseDao;
    @Autowired
    private  UserDoCourseDao userDoCourseDao;
    @Autowired
    private UserDoCourseQuestDao userDoCourseQuestDao;
    @Autowired
    private UserDoCourseSaveQuestDao userDoCourseSaveQuestDao;

    public JSONObject getCategoryChapter(String examType){
        JSONObject res = new JSONObject();
        List<CourseCategory>courseCategories=courseCategoryDao.findByExamType(examType);
        res.put("data",courseCategories);
        return res;
    }

    public JSONObject getCategorySubject(String courseCategoryId){
        JSONObject res = new JSONObject();
        List<CourseSubject>courseSubjects=courseSubjectDao.findByCourseCategoryId(courseCategoryId);
        res.put("data",courseSubjects);
        return res;
    }

    public JSONObject getCourseListData(String examType,String courseCategoryId
            ,String courseSubjectId,String userId,int page,int size){
        JSONObject res = new JSONObject();
        long total=0;
        List<CourseInfo>courseInfos=new ArrayList<>();
        UserCourse userCourse=userCourseDao.findByExamTypeAndUserId(examType,userId);
        Sort sort=new Sort(Sort.Direction.ASC,"createTime");
        if(userCourse!=null) {
            Pageable pageable = new PageRequest(page - 1, size, sort);
            Page<CourseInfo> courseInfoPage = null;
            if ("all".equals(courseCategoryId)) {
                courseInfoPage = courseInfoDao.findByExamType(examType, pageable);
            } else {
                if ("all".equals(courseSubjectId)) {
                    courseInfoPage = courseInfoDao.findObjsByCategoryId(courseCategoryId, pageable);
                } else {
                    courseInfoPage = courseInfoDao.findByCourseSubjectId(courseSubjectId, pageable);
                }
            }
            total = courseInfoPage.getTotalElements();
            courseInfos=courseInfoPage.getContent();
        }
        res.put("total",total);
        res.put("data",courseInfos);
        return res;
    }


    public JSONObject getDoTestHistoryInfo(String courseId,String userId){
        JSONObject res = new JSONObject();
        Sort sort=new Sort(Sort.Direction.DESC,"createTime");
        Pageable pageableDoTest = new PageRequest(0, 1000, sort);
        Page<UserDoCourse> userDoTestPage=userDoCourseDao.findObjsByCourseIdAndUserId(courseId,
                userId,pageableDoTest);
        List<UserDoCourse>userDoTests=userDoTestPage.getContent();
        JSONArray array=new JSONArray();
        for(UserDoCourse userDoTest:userDoTests){
            JSONObject json=new JSONObject();
            int time=DateUtil.computeDateDifferMinutes(userDoTest.getStartTime(),userDoTest.getEndTime());
            json.put("time",time);
            json.put("startTime",userDoTest.getStartTime());
            json.put("score",userDoTest.getScore());
            json.put("endTime",userDoTest.getEndTime());
            json.put("handPaperId",userDoTest.getHandPaperId());
            json.put("courseId",userDoTest.getCourseId());
            array.add(json);
        }
        res.put("data",array);
        return res;
    }

    public JSONObject getCourseQuestInfo(String courseId,String userId,int page,int size){
        JSONObject res = new JSONObject();
        Sort sort=new Sort(Sort.Direction.ASC,"createTime");
        Pageable pageable = new PageRequest(page-1, size, sort);
        Page<CourseQuest> courseQuestPage=courseQuestDao.findObjsByCourseId(courseId,pageable);
        CourseInfo courseInfo=courseInfoDao.findOne(courseId);
        List<UserDoCourseQuest>userDoCourseQuests=userDoCourseQuestDao.findByUserIdAndCourseIdAndType(userId,courseId,1);
        Map<String,UserDoCourseQuest> userDoCourseQuestMap=new HashMap<>();
        for(UserDoCourseQuest userDoCourseQuest:userDoCourseQuests){
            StringBuilder key=new StringBuilder();
            key.append(userId).append("-").append(userDoCourseQuest.getQuestId())
                    .append("-").append(userDoCourseQuest.getCourseId());
            userDoCourseQuestMap.put(key.toString(),userDoCourseQuest);
        }
        UserDoCourseSaveQuest userDoCourseSaveQuest=userDoCourseSaveQuestDao.findByUserIdAndCourseId(userId,courseId);
        Integer minute=90;
        Integer second=0;
        int noDoQuestNum=(int) courseQuestPage.getTotalElements();
        if(userDoCourseSaveQuest!=null){
            minute=userDoCourseSaveQuest.getMinute();
            second=userDoCourseSaveQuest.getSecond();
            noDoQuestNum=userDoCourseSaveQuest.getNoDoQuestNum();
        }
        JSONArray array=new JSONArray();
        for(CourseQuest courseQuest:courseQuestPage.getContent()){
            JSONObject json=(JSONObject) JSONObject.toJSON(courseQuest);
            StringBuilder key=new StringBuilder();
            key.append(userId).append("-").append(courseQuest.getId())
                    .append("-").append(courseQuest.getCourseId());
            UserDoCourseQuest userDoTestQuest=userDoCourseQuestMap.get(key.toString());
            String result=null;
            Integer isDoQuest=0;
            if(userDoTestQuest!=null){
                result=userDoTestQuest.getResult();
                isDoQuest=userDoTestQuest.getAnswerResult();
            }
            json.put("result",result);
            json.put("isDoQuest",isDoQuest);
            array.add(json);
        }
        res.put("data",array);
        res.put("total",courseQuestPage.getTotalElements());
        res.put("time",90);
        res.put("name",courseInfo.getName());
        res.put("minute",minute);
        res.put("second",second);
        res.put("noDoQuestNum",noDoQuestNum);
        return res;
    }

    public void doCourseQuestSave(DoCourseSaveReq doCourseSaveReq, String userId){
        Timestamp createTime= DateUtil.getNowTimestamp();
        Timestamp updateTime= DateUtil.getNowTimestamp();
        List<UserDoCourseQuest>userDoTestQuests=userDoCourseQuestDao.findByUserIdAndCourseIdAndType(userId,doCourseSaveReq.getCourseId(),1);
        List<DoPracticeReq>doPracticeReqList=doCourseSaveReq.getData();
        if(ObjectUtils.isEmpty(userDoTestQuests)){
            userDoTestQuests=new ArrayList<>();
            for(DoPracticeReq doPracticeReq:doPracticeReqList){
                String id= UUID.randomUUID().toString().replace("-","");
                UserDoCourseQuest userDoTestQuest=new UserDoCourseQuest();
                userDoTestQuest.setId(id);
                userDoTestQuest.setUserId(userId);
                userDoTestQuest.setQuestId(doPracticeReq.getQuestId());
                userDoTestQuest.setCourseId(doCourseSaveReq.getCourseId());
                userDoTestQuest.setResult(doPracticeReq.getResult());
                userDoTestQuest.setAnswerResult(doPracticeReq.getAnswerResult());
                userDoTestQuest.setType(1);
                userDoTestQuest.setCreateTime(createTime);
                userDoTestQuest.setUpdateTime(updateTime);
                userDoTestQuests.add(userDoTestQuest);
            }
        }else{
            Map<String,DoPracticeReq>doPracticeReqMap=new HashMap<>();
            for(DoPracticeReq doPracticeReq:doPracticeReqList){
                StringBuilder key=new StringBuilder();
                key.append(userId).append("-").append(doPracticeReq.getQuestId())
                        .append("-").append(doCourseSaveReq.getCourseId());
                doPracticeReqMap.put(key.toString(),doPracticeReq);
            }
            for(UserDoCourseQuest userDoTestQuest:userDoTestQuests){
                StringBuilder key=new StringBuilder();
                key.append(userId).append("-").append(userDoTestQuest.getQuestId())
                        .append("-").append(doCourseSaveReq.getCourseId());
                DoPracticeReq doPracticeReq=doPracticeReqMap.get(key.toString());
                userDoTestQuest.setAnswerResult(doPracticeReq.getAnswerResult());
                userDoTestQuest.setResult(doPracticeReq.getResult());
                userDoTestQuest.setUpdateTime(DateUtil.getNowTimestamp());
            }
        }
        UserDoCourseSaveQuest userDoTestSaveQuest=userDoCourseSaveQuestDao.findByUserIdAndCourseId(userId,doCourseSaveReq.getCourseId());
        if(userDoTestSaveQuest==null){
            userDoTestSaveQuest=new UserDoCourseSaveQuest();
            userDoTestSaveQuest.setId(UUID.randomUUID().toString().replace("-",""));
            userDoTestSaveQuest.setUserId(userId);
            userDoTestSaveQuest.setCourseId(doCourseSaveReq.getCourseId());
            userDoTestSaveQuest.setMinute(doCourseSaveReq.getMinute());
            userDoTestSaveQuest.setSecond(doCourseSaveReq.getSecond());
            userDoTestSaveQuest.setStartTime(doCourseSaveReq.getStartTime());
            userDoTestSaveQuest.setNoDoQuestNum(doCourseSaveReq.getNoDoQuestNum());
            userDoTestSaveQuest.setCreateTime(DateUtil.getNowTimestamp());
            userDoTestSaveQuest.setUpdateTime(DateUtil.getNowTimestamp());

        }else{
            userDoTestSaveQuest.setMinute(doCourseSaveReq.getMinute());
            userDoTestSaveQuest.setSecond(doCourseSaveReq.getSecond());
            userDoTestSaveQuest.setNoDoQuestNum(doCourseSaveReq.getNoDoQuestNum());
            userDoTestSaveQuest.setUpdateTime(DateUtil.getNowTimestamp());
        }
        userDoCourseSaveQuestDao.save(userDoTestSaveQuest);
        userDoCourseQuestDao.save(userDoTestQuests);
    }

    public void doCourseQuestHand(DoCourseSaveReq doCourseSaveReq, String userId){
        Timestamp createTime= DateUtil.getNowTimestamp();
        Timestamp updateTime= DateUtil.getNowTimestamp();
        List<UserDoCourseQuest>oldUserDoTestQuests=userDoCourseQuestDao.findByUserIdAndCourseIdAndType(userId,doCourseSaveReq.getCourseId(),1);
        userDoCourseQuestDao.delete(oldUserDoTestQuests);
        UserDoCourseSaveQuest userDoTestSaveQuest=userDoCourseSaveQuestDao.findByUserIdAndCourseId(userId,doCourseSaveReq.getCourseId());
       if(userDoTestSaveQuest!=null) {
           userDoCourseSaveQuestDao.delete(userDoTestSaveQuest);
       }
        List<DoPracticeReq>doPracticeReqList=doCourseSaveReq.getData();
        String handPaperId= UUID.randomUUID().toString().replace("-","");
        double score=0;
        String result="不及格";
        Double passScore=60.0;
        Integer testScore=100;
        int questNum=doPracticeReqList.size();
        Double questScore= Arith.div(testScore,questNum,2);
        List<UserDoCourseQuest>userDoTestQuests=new ArrayList<>();
        for(DoPracticeReq doPracticeReq:doPracticeReqList){
            if(doPracticeReq.getAnswerResult()==1){
                score+=questScore;
            }
            String id= UUID.randomUUID().toString().replace("-","");
            UserDoCourseQuest userDoTestQuest=new UserDoCourseQuest();
            userDoTestQuest.setId(id);
            userDoTestQuest.setUserId(userId);
            userDoTestQuest.setQuestId(doPracticeReq.getQuestId());
            userDoTestQuest.setCourseId(doCourseSaveReq.getCourseId());
            userDoTestQuest.setResult(doPracticeReq.getResult());
            userDoTestQuest.setAnswerResult(doPracticeReq.getAnswerResult());
            userDoTestQuest.setType(2);
            userDoTestQuest.setHandPaperId(handPaperId);
            userDoTestQuest.setCreateTime(createTime);
            userDoTestQuest.setUpdateTime(updateTime);
            userDoTestQuests.add(userDoTestQuest);
        }
        if(score>=passScore){
            result="及格";
        }
        UserDoCourse userDoTest=new UserDoCourse();
        userDoTest.setId(UUID.randomUUID().toString().replace("-",""));
        userDoTest.setHandPaperId(handPaperId);
        userDoTest.setUserId(userId);
        userDoTest.setCourseId(doCourseSaveReq.getCourseId());
        userDoTest.setScore(score);
        userDoTest.setResult(result);
        userDoTest.setStartTime(doCourseSaveReq.getStartTime());
        Date date=new Date();
        userDoTest.setEndTime(date.getTime());
        userDoTest.setCreateTime(DateUtil.getNowTimestamp());
        userDoTest.setUpdateTime(DateUtil.getNowTimestamp());
        userDoCourseQuestDao.save(userDoTestQuests);
        userDoCourseDao.save(userDoTest);
    }

    public JSONObject getHandPaperResult(String courseId,String handPaperId,String userId){
        JSONObject res = new JSONObject();
        UserDoCourse userDoTest=userDoCourseDao.findByUserIdAndHandPaperId(userId,handPaperId);
        List<UserFalseQuest> userFalseQuests=userDoCourseQuestDao.findFalseQuest(userId,handPaperId);
        Map<String,Integer>userFalseQuestMap=new HashMap<>();
        for(UserFalseQuest userFalseQuest:userFalseQuests){
            StringBuilder key=new StringBuilder(userFalseQuest.getSubjectName())
                    .append("-").append(userFalseQuest.getChapterName())
                    .append("-");
            if(userFalseQuest.getTestCentre()!=null){
                key.append(userFalseQuest.getTestCentre());
            }else{
                key.append("0");
            }
            Integer falseQuestNum=userFalseQuestMap.get(key.toString());
            if(falseQuestNum==null){
                falseQuestNum=1;
            }else{
                falseQuestNum++;
            }
            userFalseQuestMap.put(key.toString(),falseQuestNum);
        }
        JSONArray array=new JSONArray();
        for(Map.Entry<String, Integer> entries:userFalseQuestMap.entrySet()){
            JSONObject json = new JSONObject();
            String key=entries.getKey();
            String[] names=key.split("-");
            json.put("subjectName",names[0]);
            json.put("chapterName",names[1]);
            json.put("testCentre",names[2].equals("0")?"":names[2]);
            json.put("falseQuestNum",entries.getValue());
            array.add(json);
        }
        res.put("falseQuestChapterData",array);
        res.put("score",userDoTest.getScore());
        res.put("result",userDoTest.getResult());
        res.put("totalScore",100);
        return res;
    }

    public JSONObject getHandTestResultInfo(String courseId,String handPaperId,String userId,int page,int size){
        JSONObject res = new JSONObject();
        Sort sort=new Sort(Sort.Direction.ASC,"createTime");
        Pageable pageable = new PageRequest(page-1, size, sort);
        CourseInfo courseInfo=courseInfoDao.findOne(courseId);
        Page<CourseQuest> testQuestPage=courseQuestDao.findObjsByCourseId(courseId,pageable);
        UserDoCourse userDoTest=userDoCourseDao.findByUserIdAndHandPaperId(userId,handPaperId);
        List<UserDoCourseQuest>userDoTestQuests=userDoCourseQuestDao.findByUserIdAndHandPaperIdAndType(userId,handPaperId,2);
        Map<String,UserDoCourseQuest>userDoTestQuestMap=new HashMap<>();
        for(UserDoCourseQuest userDoTestQuest:userDoTestQuests){
            StringBuilder key=new StringBuilder();
            key.append(userId).append("-").append(userDoTestQuest.getQuestId())
                    .append("-").append(userDoTestQuest.getCourseId());
            userDoTestQuestMap.put(key.toString(),userDoTestQuest);
        }
        JSONArray array=new JSONArray();
        for(CourseQuest testQuest:testQuestPage.getContent()){
            JSONObject json=(JSONObject) JSONObject.toJSON(testQuest);
            StringBuilder key=new StringBuilder();
            key.append(userId).append("-").append(testQuest.getId())
                    .append("-").append(testQuest.getCourseId());
            UserDoCourseQuest userDoTestQuest=userDoTestQuestMap.get(key.toString());
            String result=null;
            Integer answerResult=0;
            if(userDoTestQuest!=null){
                result=userDoTestQuest.getResult();
                answerResult=userDoTestQuest.getAnswerResult();
            }
            json.put("result",result);
            json.put("answerResult",answerResult);
            array.add(json);
        }
        res.put("data",array);
        res.put("name",courseInfo.getName());
        res.put("total",testQuestPage.getTotalElements());
        res.put("startTime",userDoTest.getStartTime());
        res.put("endTime",userDoTest.getEndTime());
        return res;
    }
}
